import wx
from socket import *
import threading
from faker import Faker # 用来做测试生成假数据


class Client(wx.Frame):
    # 构造函数
    def __init__(self):
        # 创建实例属性
        self.name = Faker("zh_CN").name()
        self.isConnected = False
        self.client_socket = None

        # 界面布局：
        super().__init__(None, title=self.name + "聊天室", size=(450, 670), pos=(100, 50))
        # 面板
        self.pl = wx.Panel(self)
        # 创建按钮：
        # 加入聊天
        self.join_btn = wx.Button(self.pl, label="加入聊天室", pos=(10, 10), size=(200, 40))
        # 离开聊天
        self.leave_btn = wx.Button(self.pl, label="离开聊天室", pos=(220, 10), size=(200, 40))
        # 清空按钮
        self.clear_btn = wx.Button(self.pl, label="清空", pos=(10, 580), size=(200, 40))
        # 发送按钮
        self.send_btn = wx.Button(self.pl, label="发送", pos=(220, 580), size=(200, 40))
        # 创建聊天内容文本框
        self.read_text = wx.TextCtrl(self.pl, size=(420, 400), pos=(10, 60), style=wx.TE_READONLY | wx.TE_MULTILINE)
        # 创建输入文本框
        self.input_text = wx.TextCtrl(self.pl, size=(420, 100), pos=(10, 470), style=wx.TE_MULTILINE)

        # 按钮的事件绑定
        self.Bind(wx.EVT_BUTTON, self.onJoin, self.join_btn)
        self.Bind(wx.EVT_BUTTON, self.onLeave, self.leave_btn)
        self.Bind(wx.EVT_BUTTON, self.onClear, self.clear_btn)
        self.Bind(wx.EVT_BUTTON, self.onSend, self.send_btn)

    # 加入聊天室 触发
    def onJoin(self, event):
        print('Join')
        if self.isConnected == False:
            self.isConnected = True
            self.client_socket = socket()
            try:
                self.client_socket.connect(("127.0.0.1", 8999))
                # 发送用户名
                self.client_socket.send(self.name.encode("utf8"))
                # 启动接收线程
                recv_thread = threading.Thread(target=self.onRecvData)
                recv_thread.daemon = True
                recv_thread.start()
            except Exception as e:
                print(f"连接失败：{e}")
                self.isConnected = False


    def onRecvData(self):
        # 处理网络异常，避免连接中断报错
        while self.isConnected:
            try:
                text = self.client_socket.recv(1024).decode("utf8")
                self.read_text.AppendText(text + "\n")
            except Exception as e:
                print(f"接收错误：{e}")
                self.isConnected = False
                break


    # 离开聊天室 触发
    def onLeave(self, event):
        print('Leave')
        if self.isConnected:
            try:
                self.client_socket.send("断开连接".encode("utf8"))
            except Exception as e:
                print(f"断开失败：{e}")
            self.isConnected = False


    # 清空 触发
    def onClear(self, event):
        print('Clear')
        self.input_text.Clear()

    # 发送 触发
    def onSend(self, event):
        print('Send')
        if self.isConnected:
            text = self.input_text.GetValue()
            if text != "":
                self.client_socket.send(text.encode("utf8"))
                self.input_text.Clear()


# 程序入口
if __name__ == "__main__":
    # 创建应用程序对象
    app = wx.App()
    # 创建客户端窗口
    client = Client()
    # 显示客户端窗口
    client.Show()
    # 一直循环显示
    app.MainLoop()